package com.qf.data.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.common.bean.Pages;
import com.qf.common.constant.CacheConstant;
import com.qf.common.dto.DeviceCmdDto;
import com.qf.common.dto.DeviceModelValueDto;
import com.qf.common.model.DeviceCmd;
import com.qf.common.model.DeviceModelValue;
import com.qf.data.service.DeviceCmdService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author 千锋健哥
 */
@Service
public class DeviceCmdServiceImpl implements DeviceCmdService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void saveDeviceCmd(DeviceCmd cmd) {
        if (cmd == null) {
            return;
        }

        //1. 声明集合名称 device_cmd
        String collection = CacheConstant.Entity.DEVICE + CacheConstant.Suffix.CMD + "_" + cmd.getProductKey();

        //2. 给集合创建索引(索引可以加快查询效率)
        createDeviceCmdIndex(collection);

        //3. 保存指令日志到文档中
        mongoTemplate.insert(cmd, collection);
    }

    @Override
    public Page<DeviceCmd> list(DeviceCmdDto dto) {
        Page<DeviceCmd> deviceCmdPage = new Page<>();

        //1. 创建查询条件对象
        Criteria criteria = new Criteria();
        Query query = new Query(criteria);

        //2. 设置查询条件
        //判断如果租户id不为空, 根据租户id查询
        if (StringUtils.isNotEmpty(dto.getTenantId())) {
            criteria.and("tenantId").is(dto.getTenantId());
        }
        //判断如果产品key不为空, 根据产品key查询
        if (StringUtils.isNotEmpty(dto.getProductKey())) {
            criteria.and("productKey").is(dto.getProductKey());
        }
        //判断如果设备key不为空, 根据设备key查询
        if (StringUtils.isNotEmpty(dto.getDeviceKey())) {
            criteria.and("deviceKey").is(dto.getDeviceKey());
        }
        //根据时间范围查询
        if (dto.getPage().getStartTime() > 0 && dto.getPage().getEndTime() > 0) {
            criteria.and("createTime").gte(new Date(dto.getPage().getStartTime()))
                    .lte(new Date(dto.getPage().getEndTime()));
        }

        //3. 执行查询并返回结果
        //设置查询的集合名称
        String collection = CacheConstant.Entity.DEVICE + CacheConstant.Suffix.CMD + "_" + dto.getProductKey();

        //统计mongodb根据这个查询条件, 满足条件的数据总数
        long count = mongoTemplate.count(query, collection);

        //分页
        Pages page = dto.getPage();
        //计算从第几条开始查询
        long size = page.getSize() * (page.getCurrent() - 1);
        //设置从第几条开始查询
        query.limit((int) page.getSize()).skip(size);

        //排序, 第一个参数: 降序或者升序, 第二参数: 排序字段名
        query.with(Sort.by(Sort.Direction.DESC, "createTime"));

        //执行查询
        List<DeviceCmd> list = mongoTemplate.find(query, DeviceCmd.class, collection);

        //封装分页对象
        deviceCmdPage
                .setCurrent(page.getCurrent())
                .setSize(page.getSize())
                .setTotal(count)
                .setRecords(list);

        return deviceCmdPage;
    }

    /**
     * 创建集合中的索引, 索引可以加快查询效率
     * @param collection
     */
    private void createDeviceCmdIndex(String collection) {
        //创建设备key索引
        Index tenantIdIndex = new Index();
        tenantIdIndex.background()
                //第一参数, 索引字段名称, 第二参数: 排序规则
                .on("tenantId", Sort.Direction.DESC)
                //索引名字, 随便起名, 不可以重名
                .named("index_tenantId");
        mongoTemplate.indexOps(collection).ensureIndex(tenantIdIndex);

        //创建产品key索引
        Index productKeyIndex = new Index();
        productKeyIndex.background()
                //第一参数, 索引字段名称, 第二参数: 排序规则
                .on("productKey", Sort.Direction.DESC)
                //索引名字, 随便起名, 不可以重名
                .named("index_productKey");
        mongoTemplate.indexOps(collection).ensureIndex(productKeyIndex);

        //创建租户id索引
        Index deviceKeyIndex = new Index();
        deviceKeyIndex.background()
                //第一参数, 索引字段名称, 第二参数: 排序规则
                .on("deviceKey", Sort.Direction.DESC)
                //索引名字, 随便起名, 不可以重名
                .named("index_deviceKey");
        mongoTemplate.indexOps(collection).ensureIndex(deviceKeyIndex);

        //创建设备key索引
        Index createTimeIndex = new Index();
        createTimeIndex.background()
                //第一参数, 索引字段名称, 第二参数: 排序规则
                .on("createTime", Sort.Direction.DESC)
                //索引名字, 随便起名, 不可以重名
                .named("index_create_time");
        mongoTemplate.indexOps(collection).ensureIndex(createTimeIndex);
    }

}
